<?php

namespace Agp\CoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Agp\AdminBundle\Validator\Constraints as AdminAssert;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Agp\CoreBundle\Entity\Grupo;
use APY\DataGridBundle\Grid\Mapping as GRID;

/**
 * Agp\CoreBundle\Entity\Pessoa
 *
 * @ORM\Table(name="pessoa")
 * @ORM\Entity(repositoryClass="Agp\CoreBundle\Repository\PessoaRepository")
 * @UniqueEntity(fields={"nome","empresa"}, groups={"add", "edit"})
 * @UniqueEntity(fields={"nome","cpf"}, groups={"add", "edit"})
 * @UniqueEntity(fields={"cpf"}, groups={"add", "edit"})
 * @UniqueEntity(fields={"email"}, groups={"add", "edit"})
 * 
 * @GRID\Source(columns="codPessoa, nome, email")
 */
class Pessoa implements UserInterface, \Serializable
{
    
    /**
     * @var integer $codPessoa
     *
     * @ORM\Column(name="cod_pessoa", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @GRID\Column(title="Código", visible=true, type="text", size="5", primary=true)
     */
    protected $codPessoa;
    
    /**
     *
     * @var integer $empresaInc
     * @ORM\Column(name="empresa_inc", type="integer", nullable=false)
     * 
     * @GRID\Column(title="Código", type="text", align="center")
     */
    protected $empresaInc;
    
    /**
     * @var object $empresa
     *
     * @ORM\ManyToOne(targetEntity="Empresa", fetch="LAZY")
     * @ORM\JoinColumn(name="cod_empresa", referencedColumnName="cod_empresa", onDelete="cascade")
     */
    protected $empresa;

    /**
     * @var string $nome
     *
     * @ORM\Column(name="nome", type="string", length=45, nullable=false)
     * @Assert\NotBlank(groups={"add","edit"})
     * 
     * @GRID\Column(title="Nome", type="text")
     */
    protected $nome;

    /**
     * @var string $cpf
     *
     * @ORM\Column(name="cpf", type="string", length=45, nullable=false)
     * @Assert\NotBlank(groups={"add", "edit"})
     * @GRID\Column(title="Cpf", type="text")
     */
    protected $cpf;

    /**
     * @var string $rg
     *
     * @ORM\Column(name="rg", type="string", length=45, nullable=true)
     */
    protected $rg;
    
    /**
     * @var string $rg
     *
     * @ORM\Column(name="salt", type="string", length=255, nullable=true)
     */
    protected $salt;

    /**
     * @var \DateTime $dtNascimento
     *
     * @ORM\Column(name="dt_nascimento", type="date", nullable=true)
     */
    protected $dtNascimento;

    /**
     * @var string $email
     *
     * @ORM\Column(name="email", type="string", length=60, nullable=true)
     * @Assert\NotBlank(groups={"add", "edit"})
     * @Assert\Email(groups={"add", "edit"})
     * @GRID\Column(title="Email", type="text")
     */
    protected $email;

    /**
     * @var string $senha
     *
     * @ORM\Column(name="senha", type="string", length=255, nullable=true)
     * @Assert\NotBlank(groups={"add", "edit-password"})
     */
    protected $senha;
    
    /**
     * @ORM\ManyToMany(targetEntity="Grupo", inversedBy="pessoas")
     * @ORM\JoinTable(name="pessoa_grupo",
     *     joinColumns={@ORM\JoinColumn(name="cod_pessoa", referencedColumnName="cod_pessoa")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="cod_grupo", referencedColumnName="cod_grupo")}
     * )
     * 
     * @var ArrayCollection $grupos
     */
    protected $grupos;
    
    /**
     * @ORM\ManyToMany(targetEntity="TerminalEmpresa", inversedBy="pessoas")
     * @ORM\JoinTable(name="pessoa_terminal_empresa",
     *     joinColumns={@ORM\JoinColumn(name="cod_pessoa", referencedColumnName="cod_pessoa")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="cod_terminal_empresa", referencedColumnName="cod_terminal_empresa")}
     * )
     * 
     * @var ArrayCollection $terminal
     */ 
    protected $terminais;
    
    /**
     * @ORM\ManyToMany(targetEntity="Evento", mappedBy="pessoas", cascade={"all"})
     * @ORM\JoinTable(name="evento_pessoa",
     *     joinColumns={@ORM\JoinColumn(name="cod_pessoa", referencedColumnName="cod_pessoa")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="cod_evento", referencedColumnName="cod_evento")}
     * )
     * 
     * @var ArrayCollection $terminal
     */ 
    protected $eventos; 
    
    /**
     * @var string $endereco
     *
     * @ORM\Column(name="endereco", type="string", length=45, nullable=true)
     */
    protected $endereco;

    /**
     * @var string $complemento
     *
     * @ORM\Column(name="complemento", type="string", length=45, nullable=true)
     */
    protected $complemento;

    /**
     * @var string $cep
     *
     * @ORM\Column(name="cep", type="string", length=45, nullable=true)
     */
    protected $cep;

    /**
     * @var string $bairro
     *
     * @ORM\Column(name="bairro", type="string", length=45, nullable=true)
     */
    protected $bairro;
    
    /**
     * @var string $senhaTerminal
     *
     * @ORM\Column(name="senha_terminal", type="integer", nullable=true)
     * @Assert\NotBlank(groups={"add", "edit-password-terminal"})
     */
    protected $senhaTerminal;

    /**
     * @var integer $cidade
     *
     * @ORM\ManyToOne(targetEntity="Cidade", cascade={"persist"}, fetch="LAZY")
     * @ORM\JoinColumn(name="cod_cidade", referencedColumnName="id", nullable=true, onDelete="restrict")
     */
    protected $cidade;
    
    /**
     * @var string $permissaoTerminal
     *
     * @ORM\Column(name="permissao_terminal", type="set", nullable=true)
     */
    protected $permissaoTerminal;

    public function __construct() {
        $this->grupos = new ArrayCollection();
        $this->terminais = new ArrayCollection();
    }
    
    public function __toString() {
        return $this->nome;
    }

    public function getTerminaisAtivos(){
        $terminais = array();
        
        foreach ($this->terminais as $terminal){
            if ($terminal->isAtivo()){
                $terminais[] = $terminal;
            }
        } 
        
        return $terminais;
    }
    
//    public function isGruposEmpty(){
//        if ($this->grupos->isEmpty()){
//            return false;
//        }
//        return true;
//    }
    
    public function hasTerminalEmpresa($terminalEmpresa){
        
        foreach ($this->terminaisList->toArray() as $pessoaTerminal){
            if($pessoaTerminal->getTerminalEmpresa()->getCodTerminalEmpresa() === $terminalEmpresa->getCodTerminalEmpresa()){
                return true;
            }
        }
        return false;       
    }
 
        public function getId(){
        return 'class';
    }


    /* Métodos para manipulação de login */
    
    public function eraseCredentials(){}
    
    /**
     * Get password
     */
    public function getPassword() {
        return $this->getSenha();
    }
    
    /**
     * Get Salt para criptografia
     */
    public function getSalt() {
        return $this->salt;
    }
    
    /*
     * get username/email
     */
    public function getUsername() {
        return $this->email;
    }
    
    /**
     * return array de strings (role)
     * eg array("ROLE_SUPERVISOR")
     */
    public function getRoles() {
        return $this->getGrupos()->toArray();
    }
    
    public function getFirstRole(){
        return $this->grupos->first();
    }
    
    public function isSupervisor(){
        foreach ($this->grupos as $grupo){
            if ($grupo->getRole() == Grupo::ROLE_SUPERVISOR )
                return true;
        }
        
        return false;
    }
    
     public function isAdmin(){
        foreach ($this->grupos as $grupo){
            if ($grupo->getRole() == Grupo::ROLE_ADMINISTRADOR || $grupo->getRole() == Grupo::ROLE_SUPER_ADMINISTRADOR || $grupo->getRole() == Grupo::ROLE_SUPORTE)
                return true;
        }
        
        return false;
    }
    
    public function hasEvento($evento){
        
        if ($this->isAdmin())
            return true;
            
        foreach ($this->eventos as $e){
            if ($e->getCodEvento() == $evento->getCodEvento())
                return true;
        }
        
        return false;
    }

   /**
     * @Assert\True(groups={"add", "edit-senha-terminal"}, message = "Senha terminal deve ser numérica")
     */
    public function isTokenValid()
    {
        if ($this->senhaTerminal == null){
            return true;
        }
        
        return preg_match('/^[0-9]+$/', $this->senhaTerminal);
    }
    
    /**
     * Set empresa
     *
     * @param object $empresa
     * @return Empresa
     */
    public function setEmpresa($empresa)
    {
        $this->empresa = $empresa;
    
        return $this;
    }

    /**
     * Get e
     *
     * @return object 
     */
    public function getEmpresa()
    {
        return $this->empresa;
    }
    
    /**
     * Set codPessoa
     *
     * @param integer $codPessoa
     * @return Pessoa
     */
    public function setCodPessoa($codPessoa)
    {
        $this->codPessoa = $codPessoa;
        return $this;
    }

    /**
     * Get codPessoa
     *
     * @return integer 
     */
    public function getCodPessoa()
    {
        return $this->codPessoa;
    }

    /**
     * Set nome
     *
     * @param string $nome
     * @return Pessoa
     */
    public function setNome($nome)
    {
        $this->nome = mb_strtoupper($nome, 'UTF-8');
    
        return $this;
    }

    /**
     * Get nome
     *
     * @return string 
     */
    public function getNome()
    {
        return $this->nome;
    }

    /**
     * Set cpf
     *
     * @param string $cpf
     * @return Pessoa
     */
    public function setCpf($cpf)
    {
        $this->cpf = $cpf;
    
        return $this;
    }

    /**
     * Get cpf
     *
     * @return string 
     */
    public function getCpf()
    {
        return $this->cpf;
    }

    /**
     * Set rg
     *
     * @param string $rg
     * @return Pessoa
     */
    public function setRg($rg)
    {
        $this->rg = $rg;
    
        return $this;
    }

    /**
     * Get rg
     *
     * @return string 
     */
    public function getRg()
    {
        return $this->rg;
    }

    /**
     * Set dtNascimento
     *
     * @param \DateTime $dtNascimento
     * @return Pessoa
     */
    public function setDtNascimento($dtNascimento)
    {
        $this->dtNascimento = $dtNascimento;
    
        return $this;
    }

    /**
     * Get dtNascimento
     *
     * @return \DateTime 
     */
    public function getDtNascimento()
    {
        return $this->dtNascimento;
    }

    /**
     * Set email
     *
     * @param string $email
     * @return Pessoa
     */
    public function setEmail($email)
    {
        $this->email = $email;
    
        return $this;
    }

    /**
     * Get email
     *
     * @return string 
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * Set senha
     *
     * @param string $senha
     * @return Pessoa
     */
    public function setSenha($senha)
    {
        $this->senha = $senha;
    
        return $this;
    }

    /**
     * Get senha
     *
     * @return string 
     */
    public function getSenha()
    {
        return $this->senha;
    }
    
    /**
     * Add grupos
     *
     * @param Agp\CoreBundle\Entity\Grupo $grupos
     */
    public function addRole(\Agp\CoreBundle\Entity\Grupo $grupo)
    {
        $this->grupos[] = $grupo;
    }
    
    /**
     * Set the grupos.
     * 
     */
    public function setGrupos($entity)
    {
        $grupos = new ArrayCollection;
        $grupos->clear();
        $grupos->add($entity);
        $this->grupos = $grupos;
    }
    
    /**
     * Gets the grupos.
     *
     * @return ArrayCollection A Doctrine ArrayCollection
     */
    public function getGrupos()
    {
        return $this->grupos;
    }
    
    public function setSalt($salt){
        $this->salt = $salt;
    }
    
    /**
     * Add $terminais
     *
     * @param Agp\CoreBundle\Entity\TerminalEmpresa $terminais
     */
    public function addTerminal(\Agp\CoreBundle\Entity\TerminalEmpresa $terminal)
    {
        $this->terminais[] = $terminal;
    }

    /**
     * Get terminais
     *  
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getTerminais()
    {
        return $this->terminais;
    }
    
     /**
     * Set terminais
     *
     */
    public function setTerminais($terminais)
    {
        $this->terminais = $terminais;
    }
    
    public function getEndereco() {
        return $this->endereco;
    }

    public function setEndereco($endereco) {
        $this->endereco = $endereco;
    }

    public function getComplemento() {
        return $this->complemento;
    }

    public function setComplemento($complemento) {
        $this->complemento = $complemento;
    }

    public function getCep() {
        return $this->cep;
    }

    public function setCep($cep) {
        $this->cep = $cep;
    }

    public function getBairro() {
        return $this->bairro;
    }

    public function setBairro($bairro) {
        $this->bairro = $bairro;
    }

    public function getCidade() {
        return $this->cidade;
    }

    public function setCidade($cidade) {
        $this->cidade = $cidade;
    }
    
    public function getSenhaTerminal() {
        return $this->senhaTerminal;
    }

    public function setSenhaTerminal($senhaTerminal) {
        $this->senhaTerminal = $senhaTerminal;
    }
    
    public function getPermissaoTerminal() {
        return $this->permissaoTerminal;
    }

    public function setPermissaoTerminal($permissaoTerminal) {
        $this->permissaoTerminal = $permissaoTerminal;
    }
    
    public function addEvento($e){
        $this->eventos[] = $e;
        $e->addPessoa($this);
        
    }
    
    public function getEventos() {
        return $this->eventos;
    }
    
    public function removeEvento($e)
    {
        $e->removePessoa($this);
        $this->eventos->removeElement($e);
    }

    public function setEventos($eventos) {
        
        foreach ($eventos as $e){
            $e->addPessoa($this);
        }
        
        $this->eventos = $eventos;
    }
    
    public static function getPermissaoTerminalList(){
        return array('Cortesia' => 'Cortesia',
                            'Comissionado' => 'Comissionado',
                            'Movimentacao' => 'Movimentação',
                            'Fechamento' => 'Fechamento',
                            'Relatórios' => 'Relatórios',
                            'Cadastro de produto' => 'Cadastro de produto',
                            'Cadastro de atendente' => 'Cadastro de atendente',
                            'Fechamento de atendente' => 'Fechamento de atendente',
                            'Configuracao' => 'Configuração',
                            'Estorno' => 'Estorno / Cancelamento',
                            'Fechamento Offline' => 'Fechamento Offline');
    }
    
    public function getEmpresaInc() {
        return $this->empresaInc;
    }

    public function setEmpresaInc($empresaInc) {
        $this->empresaInc = $empresaInc;
    }
    
    /**
     * @see \Serializable::serialize()
     */
    public function serialize()
    {
        /*
         * ! Don't serialize $roles field !
         */
        return \serialize(array(
            $this->codPessoa,
            $this->bairro,
            $this->cep,
            $this->cidade,
            $this->complemento,
            $this->cpf,
            $this->dtNascimento,
            $this->email,
            $this->empresa,
            $this->empresaInc,
            $this->endereco,
            $this->nome,
            $this->permissaoTerminal,
            $this->rg,
            $this->salt,
            $this->senha,
            $this->senhaTerminal
        ));
    }

    /**
     * @see \Serializable::unserialize()
     */
    public function unserialize($serialized)
    {
        list (
            $this->codPessoa,
            $this->bairro,
            $this->cep,
            $this->cidade,
            $this->complemento,
            $this->cpf,
            $this->dtNascimento,
            $this->email,
            $this->empresa,
            $this->empresaInc,
            $this->endereco,
            $this->nome,
            $this->permissaoTerminal,
            $this->rg,
            $this->salt,
            $this->senha,
            $this->senhaTerminal
        ) = \unserialize($serialized);
    }
}